package com.wn.common.myException;

import com.aliyun.oss.ServiceException;
import com.wn.common.pojo.Rsp;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @BelongsProject: springboot_pxx
 * @BelongsPackage: com.wn.exception
 * @Author: lhq
 * @Description:
 */


@RestControllerAdvice //全局异常
public class GlobalException {

    private static Logger log = LoggerFactory.getLogger(GlobalException.class);

    @ExceptionHandler(ServiceException.class)
    public Rsp MyServiceException(Exception e){
        log.info("出现了业务异常");
        e.printStackTrace();
        return new Rsp().fail().msg(e.getMessage());
    }

    @ExceptionHandler(ArithmeticException.class)
    public Rsp MyArithmeticException(Exception e){
        log.info("出现了算数异常");
        e.printStackTrace();
        return new Rsp().fail().msg(e.getMessage());
    }

    @ExceptionHandler(NullPointerException.class)
    public Rsp MyNullPointerException(Exception e){
        log.info("出现了空指向异常");
        e.printStackTrace();
        return new Rsp().fail().msg(e.getMessage()+"输入值为空");
    }

    @ExceptionHandler(IOException.class)
    public Rsp MyIOException(Exception e){
        log.info("出现了IO流异常");
        e.printStackTrace();
        return new Rsp().fail().msg("输入格式错误");
    }
    @ExceptionHandler(ClassNotFoundException.class)
    public Rsp MyClassNotFoundException(Exception e){
        log.info("出现了类未找到异常");
        return new Rsp().fail().msg(e.getMessage());
    }
    @ExceptionHandler(ProductStockNotEnoughException.class)
    public Rsp MyProductStockNotEnoughException(Exception e){
        log.info("货物库存不足！");
        return new Rsp().fail().msg(e.getMessage());
    }
    @ExceptionHandler(MalformedJwtException.class)
    public Rsp TokenNotExistException(Exception e){
        log.info("token不存在");
        return new Rsp().fail().msg("token不存在").code(50003);
    }


    @ExceptionHandler(ExpiredJwtException.class)
    public Rsp ExpiredJwtException(Exception e){
        log.info("登录信息已经过期");
        return new Rsp().fail().msg("登录信息已经过期").code(50005);
    }
    /**
     * 获取所有的后端校验异常
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Map<String,Object> datavalidatorException(MethodArgumentNotValidException e){
        BindingResult bindingResult=e.getBindingResult();
        System.out.println("捕捉到数据校验异常");
        Map<String,Object> map = new HashMap<>();
        log.info("后端校验数据异常");
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        //遍历获得的所有出现异常的校验数据
        StringBuffer errMsg = new StringBuffer();
        fieldErrors.forEach( error->{
            //取出校验不通过的属性名称
            String fieldName = error.getField();
            //拿到属性的message属性
            String message = error.getDefaultMessage();
            //一次只显示一种错误提示
            if(errMsg.length()==0)
            errMsg.append(message);
            map.put(fieldName,message);
            map.put("code",50000);
            e.printStackTrace();
        });
        map.put("msg",errMsg);
        log.info("异常map="+map);
        return map;
    }



}
